package org.cmb.homework.service;


import org.cmb.homework.Good;
import org.cmb.homework.User;
import org.cmb.homework.entity.BuyLog;
import org.cmb.homework.util.Utils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class OrderService {

    /**
     * 用来存储所有的购买记录
     * 这里必须使用 同步集合，因为存在多个线程并发添加数据到集合中，ArrayList会直接报错
     */
    private static List<BuyLog> buyLogs = new CopyOnWriteArrayList<>();

    /**
     * 类似于抢票操作，只应该提供用户和商品信息即可
     *
     * @param user 用户购买信息
     * @param good 购买的商品信息
     * @param goodNums 购买的数量
     * @return true: 购买成功 false: 购买失败
     */
    public boolean buyFD(User user, Good good, int goodNums) {
        //1.校验库存和用户的积分信息
        Integer inStock = good.getInStock().getReference();
        if (inStock <= 0 || inStock < goodNums || user.getRemainingPoints() < goodNums * good.getPrice()) return false;

        //2.乐观锁更新库存（或者直接加锁更新库存）
        //使用带时间戳的原子引用类型来进行CAS操作，操作成功则说明购买成功---对应使用数据库的乐观锁操作
/*        synchronized (good){
            good.getInStock().set(inStock - goodNums, good.getInStock().getStamp() + 1);
        }*/
        int version = good.getInStock().getStamp();
        boolean result = good.getInStock().compareAndSet(inStock, inStock - goodNums, version, version + 1);

        //如果结果为false则说明该用户对于该商品的购买失败了
        if (!result){
            return false;
        }

        //3.创建订单信息更新用户的数据
        createBuyLog(user, good, goodNums);
        updateUserInfo(user, good, goodNums);

        //4.返回结果---实际可以返回生成的订单号
        return true;
    }

    /**
     * 更新用户的数据信息
     * @param user user信息
     * @param good 商品信息
     * @param goodNums 购买数量
     */
    private void updateUserInfo(User user, Good good, int goodNums) {
        user.setRemainingPoints(user.getRemainingPoints() - goodNums * good.getPrice());
        user.setTotalNum(user.getTotalNum() + 1);
    }

    /**
     * 创建购买记录
     * @param user 购买用户
     * @param good 购买商品
     * @param goodNums 购买数量
     */
    private void createBuyLog(User user, Good good, int goodNums) {
        BuyLog buyLog = new BuyLog();
        buyLog.setOrderNum(Utils.generateOrderNum())
                .setCreateTime(new Date())
                .setBuyNum(goodNums)
                .setUserId(user.getUserID())
                .setGoodId(good.getId());
        System.out.println("【系统提示】：商品购买成功" + buyLog);
        buyLogs.add(buyLog);
        System.out.println("【系统提示】：当前的购买数量为：" + buyLogs.size());
    }


    public List<BuyLog> getBuyLogs(){return buyLogs;}

}
